package com.yxsk.relay.job.endpoint.combine.auto;

import com.yxsk.relay.job.component.endpoint.config.RelayJobAdminConfig;
import com.yxsk.relay.job.component.endpoint.config.RelayJobSlaveConfig;
import com.yxsk.relay.job.component.endpoint.handle.context.RelayJobExecutorManager;
import com.yxsk.relay.job.component.endpoint.handle.context.RelayJobHandlerAnnotationDriver;
import com.yxsk.relay.job.component.endpoint.handle.context.RelayJobHandlerScan;
import com.yxsk.relay.job.endpoint.combine.config.*;
import com.yxsk.relay.job.endpoint.combine.loader.ApplicationConfigLoader;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description
 * @Author 11376
 * @CreateTime 2019/9/10 21:57
 */
@Slf4j
public class RelayJobEndpointAutoCombine {

    private static final boolean STARED = false;

    protected RelayJobAdminConfig adminConfig;

    protected RelayJobSlaveConfig slaveConfig;

    private LogServiceConfig logConfig;

    public void start() {
        synchronized (RelayJobEndpointAutoCombine.class) {
            if (!STARED) {
                // 加载配置
                loadConfig();

                // 启动 log service
                startLogService();

                // 扫描 job handler
                scanJobHandler();

                // 启动 RPC 服务
                startRpcService();

                // 启动 admin注册服务
                startAdminRegistry();

                // print banner
                printBanner();
            }
        }

    }

    private void printBanner() {
        System.out.println("    #############################################################");
        System.out.println("   #                                                             #");
        System.out.println("  #                           RELAY-JOB                           #");
        System.out.println("   #                                                             #");
        System.out.println("    #############################################################");
    }

    private void startRpcService() {
        EndpointCombineAutoConfig config = new NetServerConfig(this.adminConfig, this.slaveConfig, this.logConfig.logStream());
        config.startConfig();
    }

    private void startAdminRegistry() {
        EndpointCombineAutoConfig registryConfig = new AdminRegistryConfig(this.adminConfig, this.slaveConfig);
        registryConfig.startConfig();
    }

    private void scanJobHandler() {
        if (log.isDebugEnabled()) {
            log.debug("Start scanning job handle...");
        }
        RelayJobHandlerScan jobHandlerScan = this.getClass().getAnnotation(RelayJobHandlerScan.class);
        if (jobHandlerScan != null) {
            RelayJobHandlerAnnotationDriver driver = new RelayJobHandlerAnnotationDriver();
            driver.drive(jobHandlerScan);
        } else {
            // 以本类最为基础包扫描
            String[] basePackages = {this.getClass().getPackage().getName()};
            RelayJobExecutorManager.load(basePackages);
        }
        if (log.isDebugEnabled()) {
            log.debug("Job handle scan complete.");
        }
    }

    /**
     * @return
     * @Author 1137
     * @Description 初始化日志组件
     * @Date
     * @Param
     */
    private void startLogService() {
        this.logConfig = new LogServiceConfig(this.slaveConfig);
        this.logConfig.startConfig();
    }


    private void loadConfig() {
        ApplicationConfigLoader configLoader = new ApplicationConfigLoader();
        EndpointConfigCombine configCombine = configLoader.load(configPath(), EndpointConfigCombine.class);
        this.adminConfig = configCombine.getAdmin();
        this.slaveConfig = configCombine.getSlave();
    }

    protected String configPath() {
        return "classpath:relay-job.yml";
    }

}
